package com.example.litterpainterdemo.draw.view

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.PointF
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import androidx.lifecycle.LifecycleOwner
import com.example.litterpainterdemo.R
import com.example.litterpainterdemo.draw.shapes.BezelShape
import com.example.litterpainterdemo.draw.shapes.CircleShape
import com.example.litterpainterdemo.draw.shapes.CurveShape
import com.example.litterpainterdemo.draw.shapes.LineShape
import com.example.litterpainterdemo.draw.shapes.RectangleShape
import com.example.litterpainterdemo.draw.shapes.Shape
import com.example.litterpainterdemo.draw.shapes.TriangleShape

class DrawView(context: Context,attrs:AttributeSet?):View(context, attrs) {
    var viewModel: DrawViewModel? = null
    var lifecycleOwner: LifecycleOwner? = null
    var toolType: ToolType = ToolType.None //工具
    var paintColor = 0
    var strokeWidth = 0
    private val shapeList = arrayListOf<Shape>()  //保存所有需要绘制的形状
    private var currentShape:Shape? = null //记录当前形状
    private var mTouchX = 0f
    private var mTouchY = 0f
    private var behaviorType = BehaviorType.Draw //记录当前是什么行为,默认是绘制形状
    var mBitmap: Bitmap? = null
        set(value) {
            field = value
            field?.let {
                invalidate()
            }
        }

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
        super.onSizeChanged(w, h, oldw, oldh)

        //监听数据
        if(viewModel != null && lifecycleOwner != null){
            //监听工具类型
            viewModel!!.toolType.observe(lifecycleOwner!!){
                toolType = it
                if(it == ToolType.Delete){
                    shapeList.clear()
                    currentShape = null
                    invalidate()
                }

                if(it == ToolType.Back){//撤销
                    if(shapeList.size > 0){
                        shapeList.removeLast()
                        currentShape = null
                        invalidate()
                    }
                }
            }

            //监听颜色
            viewModel!!._color.observe(lifecycleOwner!!){
                paintColor = it
            }

            //监听线的粗细
            viewModel!!.mLineWidth.observe(lifecycleOwner!!){
                strokeWidth = it.toInt()
            }
        }
    }

    //绘制
    override fun onDraw(canvas: Canvas?) {
        canvas?.let {
            mBitmap?.let { bitmap->
                canvas.drawBitmap(bitmap,0f,0f,null)
            }

            shapeList.forEach {
                it.draw(canvas)
            }
        }
    }

    @SuppressLint("ClickableViewAccessibility")
    override fun onTouchEvent(event: MotionEvent?): Boolean {
        when(event?.action){
            MotionEvent.ACTION_DOWN -> {
                addShape(event.x,event.y)
                mTouchX = event.x
                mTouchY = event.y
            }
            MotionEvent.ACTION_MOVE -> {
                when(behaviorType){
                    BehaviorType.Draw -> {changeShape(event.x,event.y)}
                    BehaviorType.Translate -> {
                        currentShape?.move(event.x-mTouchX,event.y-mTouchY)
                        invalidate()
                        mTouchX = event.x
                        mTouchY = event.y
                    }
                    else -> {}
                }
            }
            MotionEvent.ACTION_UP -> {
                currentShape = null
                behaviorType = BehaviorType.Draw
            }
        }
        return true
    }

    private fun addShape(mx:Float,my:Float){
        when(toolType){
            ToolType.None -> {
                currentShape = null
            }
            ToolType.Line -> {
                LineShape().also {
                    it.paintColor = paintColor
                    it.strokeWidth = strokeWidth
                    it.startPoint = PointF(mx,my)
                    currentShape = it
                    shapeList.add(it)
                }
            }
            ToolType.Rectangle -> {
                RectangleShape().also {
                    it.paintColor = paintColor
                    it.strokeWidth = strokeWidth
                    it.startPoint = PointF(mx,my)
                    currentShape = it
                    shapeList.add(it)
                }
            }
            ToolType.Circle -> {
                CircleShape().also {
                    it.paintColor = paintColor
                    it.strokeWidth = strokeWidth
                    it.startPoint = PointF(mx,my)
                    currentShape = it
                    shapeList.add(it)
                }
            }
            ToolType.Triangle -> {
                TriangleShape().also {
                    it.paintColor = paintColor
                    it.strokeWidth = strokeWidth
                    it.startPoint = PointF(mx,my)
                    currentShape = it
                    shapeList.add(it)
                }
            }
            ToolType.Curve -> {
                CurveShape().also {
                    it.paintColor = paintColor
                    it.strokeWidth = strokeWidth
                    it.startPoint = PointF(mx,my)
                    currentShape = it
                    shapeList.add(it)
                }
            }
            ToolType.Bezel -> {
                BezelShape().also {
                    it.paintColor = paintColor
                    it.strokeWidth = strokeWidth
                    it.startPoint = PointF(mx,my)
                    currentShape = it
                    shapeList.add(it)
                }
            }
            ToolType.Eraser -> {
                CurveShape().also {
                    it.strokeWidth = strokeWidth
                    it.startPoint = PointF(mx,my)
                    currentShape = it
                    shapeList.add(it)
                    it.paintColor = resources.getColor(R.color.background_dark,null)
                }
            }
            ToolType.Move -> {
                behaviorType = BehaviorType.Translate
                //判断触摸点是否在某个形状内
                currentShape = insideTheShape(mx,my)
            }
            ToolType.Brush -> { //填充
                currentShape = insideTheShape(mx,my)
                currentShape?.let {
                    it.fillShape(paintColor)
                    invalidate()
                    currentShape = null
                }
            }
            else ->{}
        }
    }

    private fun insideTheShape(dx:Float,dy:Float):Shape?{
        for (i in shapeList.size-1 downTo 0){
            val shape = shapeList[i]
            if(shape.insideTheShape(dx,dy)){
                return shape
            }
        }
        return null
    }


    private fun changeShape(mx:Float,my:Float){
        currentShape?.let {
            it.endPoint = PointF(mx,my)
            invalidate()
        }
    }

    fun isEmpty() = shapeList.isEmpty()

}